# ------------------------------------------------------------------------------
# Web-based Computer Vision Detection System
# ------------------------------------------------------------------------------
# Flask 应用 - 提供基于浏览器的视觉检测服务
# ------------------------------------------------------------------------------

from flask import Flask, render_template, Response, request, jsonify
import cv2
import threading
import os
import sys

# 添加检测模块路径
sys.path.append(os.path.dirname(os.path.abspath(__file__)))

from detection_modules.camera_test import CameraTestDetector
from detection_modules.face_detector import FaceDetector
from detection_modules.motion_detector import MotionDetector
from detection_modules.color_tracker import ColorTracker
from detection_modules.yolo_detector import YOLODetector

app = Flask(__name__)

# 配置
CAMERA_ID = 0
IMAGE_WIDTH = 640
IMAGE_HEIGHT = 480

# 全局变量
camera = None
camera_lock = threading.Lock()
current_detector = None
detector_lock = threading.Lock()

# 检测器实例缓存
detectors = {
    'camera_test': None, #
    'face_detection': None,
    'motion_detection': None,
    'color_tracking': None,
    'yolo_detection': None
}


def get_camera():
    """获取摄像头实例（单例模式）"""
    global camera
    if camera is None or not camera.isOpened():
        with camera_lock:
            if camera is None or not camera.isOpened():
                camera = cv2.VideoCapture(CAMERA_ID)
                camera.set(cv2.CAP_PROP_FRAME_WIDTH, IMAGE_WIDTH)
                camera.set(cv2.CAP_PROP_FRAME_HEIGHT, IMAGE_HEIGHT)
    return camera


def get_detector(detection_type):
    """获取或创建检测器实例"""
    global detectors
    
    if detectors[detection_type] is None:
        with detector_lock:
            if detectors[detection_type] is None:
                if detection_type == 'camera_test':
                    detectors[detection_type] = CameraTestDetector()
                elif detection_type == 'face_detection':
                    detectors[detection_type] = FaceDetector()
                elif detection_type == 'motion_detection':
                    detectors[detection_type] = MotionDetector()
                elif detection_type == 'color_tracking':
                    detectors[detection_type] = ColorTracker()
                elif detection_type == 'yolo_detection':
                    detectors[detection_type] = YOLODetector()
                    
    return detectors[detection_type]


def generate_frames(detection_type):
    """生成视频帧"""
    cam = get_camera()
    detector = get_detector(detection_type)
    
    while True:
        success, frame = cam.read()
        if not success:
            break
        
        try:
            # 使用检测器处理帧
            processed_frame = detector.process_frame(frame)
            
            # 编码为 JPEG
            ret, buffer = cv2.imencode('.jpg', processed_frame, 
                                      [cv2.IMWRITE_JPEG_QUALITY, 85])
            if not ret:
                continue
                
            frame_bytes = buffer.tobytes()
            
            # 生成 multipart 响应
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
                   
        except Exception as e:
            print(f"处理帧时出错: {e}")
            continue


@app.route('/')
def index():
    """主页 - 显示所有功能"""
    return render_template('index.html')


@app.route('/camera_test')
def camera_test():
    """相机测试页面"""
    return render_template('camera_test.html')


@app.route('/face_detection')
def face_detection():
    """人脸检测页面"""
    return render_template('face_detection.html')


@app.route('/motion_detection')
def motion_detection():
    print('motion_detection-----运动检测页面启动')
    """运动检测页面"""
    return render_template('motion_detection.html')


@app.route('/color_tracking')
def color_tracking():
    """颜色追踪页面"""
    return render_template('color_tracking.html')


@app.route('/yolo_detection')
def yolo_detection():
    """YOLO 物体检测页面"""
    return render_template('yolo_detection.html')


@app.route('/video_feed/<detection_type>')
def video_feed(detection_type):
    """视频流路由"""
    if detection_type not in detectors:
        return "Invalid detection type", 400
    
    return Response(generate_frames(detection_type),
                   mimetype='multipart/x-mixed-replace; boundary=frame')


@app.route('/api/update_color_range', methods=['POST'])
def update_color_range():
    """更新颜色追踪的 HSV 范围"""
    try:
        data = request.json
        hsv_min = data.get('hsv_min', [50, 80, 80])
        hsv_max = data.get('hsv_max', [120, 255, 255])
        
        detector = get_detector('color_tracking')
        detector.update_color_range(hsv_min, hsv_max)
        
        return jsonify({'status': 'success', 'message': '颜色范围已更新'})
    except Exception as e:
        return jsonify({'status': 'error', 'message': str(e)}), 500


@app.route('/api/camera_status')
def camera_status():
    """检查摄像头状态"""
    cam = get_camera()
    is_opened = cam.isOpened()
    return jsonify({'status': 'ok' if is_opened else 'error', 'opened': is_opened})


if __name__ == '__main__':
    print("=" * 70)
    print("🚀 Web 视觉检测系统启动中...")
    print("=" * 70)
    print(f"📷 摄像头 ID: {CAMERA_ID}")
    print(f"📐 分辨率: {IMAGE_WIDTH}x{IMAGE_HEIGHT}")
    print()
    print("🌐 访问地址:")
    print(f"   本地访问: http://localhost:5000")
    print(f"   局域网访问: http://<你的IP地址>:5000")
    print()
    print("💡 提示: 使用 Ctrl+C 停止服务器")
    print("=" * 70)
    print()
    
    try:
        # 启动 Flask 应用（允许局域网访问）
        app.run(host='0.0.0.0', port=5000, debug=False, threaded=True)
    except KeyboardInterrupt:
        print("\n\n正在关闭服务器...")
    finally:
        # 清理资源
        if camera is not None:
            camera.release()
        cv2.destroyAllWindows()
        print("服务器已关闭。")

